/*
 * Copyright 2024 Adobe. All rights reserved.
 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
 * OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

// Mapping of v5 static colors to latest s2 colors. This was generated by finding the closest
// color perceptually using deltaE in the oklab color space. Since the static colors are not
// supposed to change between light and dark color schemes, we find the closest value for each
// and map them both. See scripts/mapStaticColors.mjs for more details.
const staticColors = {
  'static-blue': {default: 'blue-1100', dark: 'blue-500'},
  'static-gray-50': {default: 'gray-25', dark: 'gray-1000'},
  'static-gray-75': {default: 'gray-25', dark: 'gray-1000'},
  'static-gray-100': {default: 'gray-25', dark: 'gray-1000'},
  'static-gray-200': {default: 'gray-100', dark: 'silver-1400'},
  'static-gray-300': {default: 'gray-300', dark: 'gray-800'},
  'static-gray-400': {default: 'silver-500', dark: 'gray-700'},
  'static-gray-500': {default: 'gray-500', dark: 'silver-1000'},
  'static-gray-600': {default: 'gray-600', dark: 'gray-500'},
  'static-gray-700': {default: 'silver-1200', dark: 'gray-400'},
  'static-gray-800': {default: 'silver-1400', dark: 'gray-75'},
  'static-gray-900': {default: 'gray-1000', dark: 'gray-25'},
  'static-blue-200': {default: 'blue-500', dark: 'cyan-1200'},
  'static-blue-300': {default: 'cyan-600', dark: 'cyan-1100'},
  'static-blue-400': {default: 'cyan-700', dark: 'cyan-1000'},
  'static-blue-500': {default: 'blue-800', dark: 'blue-900'},
  'static-blue-600': {default: 'blue-900', dark: 'blue-700'},
  'static-blue-700': {default: 'blue-1100', dark: 'blue-500'},
  'static-blue-800': {default: 'blue-1200', dark: 'blue-400'},
  'static-red-400': {default: 'red-800', dark: 'red-800'},
  'static-red-500': {default: 'red-900', dark: 'red-700'},
  'static-red-600': {default: 'red-1000', dark: 'red-600'},
  'static-red-700': {default: 'red-1100', dark: 'red-500'},
  'static-orange-400': {default: 'orange-600', dark: 'orange-1100'},
  'static-orange-500': {default: 'orange-700', dark: 'orange-1000'},
  'static-orange-600': {default: 'orange-800', dark: 'orange-800'},
  'static-orange-700': {default: 'orange-900', dark: 'orange-700'},
  'static-green-400': {default: 'green-700', dark: 'green-1000'},
  'static-green-500': {default: 'green-800', dark: 'green-800'},
  'static-green-600': {default: 'green-900', dark: 'green-700'},
  'static-green-700': {default: 'green-1000', dark: 'green-600'},
  'static-celery-200': {default: 'celery-400', dark: 'celery-1300'},
  'static-celery-300': {default: 'celery-500', dark: 'celery-1200'},
  'static-celery-400': {default: 'celery-600', dark: 'celery-1100'},
  'static-celery-500': {default: 'celery-700', dark: 'celery-1000'},
  'static-celery-600': {default: 'celery-800', dark: 'celery-900'},
  'static-celery-700': {default: 'celery-900', dark: 'celery-700'},
  'static-chartreuse-300': {default: 'chartreuse-400', dark: 'chartreuse-1300'},
  'static-chartreuse-400': {default: 'chartreuse-500', dark: 'chartreuse-1200'},
  'static-chartreuse-500': {default: 'chartreuse-600', dark: 'chartreuse-1100'},
  'static-chartreuse-600': {default: 'chartreuse-700', dark: 'chartreuse-1000'},
  'static-chartreuse-700': {default: 'chartreuse-800', dark: 'chartreuse-800'},
  'static-yellow-200': {default: 'yellow-200', dark: 'yellow-1400'},
  'static-yellow-300': {default: 'yellow-300', dark: 'yellow-1400'},
  'static-yellow-400': {default: 'yellow-400', dark: 'yellow-1300'},
  'static-yellow-500': {default: 'yellow-500', dark: 'yellow-1200'},
  'static-yellow-600': {default: 'yellow-600', dark: 'yellow-1100'},
  'static-yellow-700': {default: 'yellow-700', dark: 'yellow-1000'},
  'static-magenta-200': {default: 'magenta-600', dark: 'magenta-1100'},
  'static-magenta-300': {default: 'magenta-600', dark: 'magenta-1000'},
  'static-magenta-400': {default: 'magenta-800', dark: 'magenta-800'},
  'static-magenta-500': {default: 'magenta-900', dark: 'magenta-700'},
  'static-magenta-600': {default: 'magenta-1000', dark: 'magenta-600'},
  'static-magenta-700': {default: 'magenta-1100', dark: 'magenta-500'},
  'static-fuchsia-400': {default: 'fuchsia-700', dark: 'fuchsia-1000'},
  'static-fuchsia-500': {default: 'fuchsia-800', dark: 'fuchsia-900'},
  'static-fuchsia-600': {default: 'fuchsia-900', dark: 'fuchsia-700'},
  'static-fuchsia-700': {default: 'fuchsia-1000', dark: 'fuchsia-600'},
  'static-purple-400': {default: 'purple-700', dark: 'purple-1000'},
  'static-purple-500': {default: 'purple-800', dark: 'purple-800'},
  'static-purple-600': {default: 'purple-900', dark: 'purple-700'},
  'static-purple-700': {default: 'purple-1000', dark: 'purple-600'},
  'static-purple-800': {default: 'purple-1200', dark: 'purple-500'},
  'static-indigo-200': {default: 'indigo-500', dark: 'indigo-1200'},
  'static-indigo-300': {default: 'indigo-600', dark: 'indigo-1100'},
  'static-indigo-400': {default: 'indigo-700', dark: 'indigo-1000'},
  'static-indigo-500': {default: 'indigo-800', dark: 'indigo-900'},
  'static-indigo-600': {default: 'blue-900', dark: 'blue-700'},
  'static-indigo-700': {default: 'blue-1000', dark: 'blue-600'},
  'static-seafoam-200': {default: 'turquoise-500', dark: 'turquoise-1200'},
  'static-seafoam-300': {default: 'turquoise-600', dark: 'turquoise-1100'},
  'static-seafoam-400': {default: 'turquoise-700', dark: 'turquoise-1000'},
  'static-seafoam-500': {default: 'turquoise-800', dark: 'seafoam-800'},
  'static-seafoam-600': {default: 'seafoam-900', dark: 'seafoam-700'},
  'static-seafoam-700': {default: 'seafoam-1000', dark: 'seafoam-600'}
};

// Mapping from v5 colors to v6 colors. These are in the light color scheme.
const v5ColorsToV6Colors = {
  'celery-400': 'celery-600',
  'celery-500': 'celery-700',
  'celery-600': 'celery-800',
  'celery-700': 'celery-900',
  'chartreuse-400': 'chartreuse-500',
  'chartreuse-500': 'chartreuse-600',
  'chartreuse-600': 'chartreuse-700',
  'chartreuse-700': 'chartreuse-800',
  'yellow-400': 'yellow-400',
  'yellow-500': 'yellow-500',
  'yellow-600': 'yellow-600',
  'yellow-700': 'yellow-700',
  'magenta-400': 'magenta-800',
  'magenta-500': 'magenta-900',
  'magenta-600': 'magenta-1000',
  'magenta-700': 'magenta-1100',
  'fuchsia-400': 'fuchsia-800',
  'fuchsia-500': 'fuchsia-900',
  'fuchsia-600': 'fuchsia-1000',
  'fuchsia-700': 'fuchsia-1100',
  'purple-400': 'purple-800',
  'purple-500': 'purple-900',
  'purple-600': 'purple-1000',
  'purple-700': 'purple-1100',
  'indigo-400': 'indigo-800',
  'indigo-500': 'indigo-900',
  'indigo-600': 'indigo-1000',
  'indigo-700': 'indigo-1100',
  'seafoam-400': 'seafoam-700',
  'seafoam-500': 'seafoam-800',
  'seafoam-600': 'seafoam-900',
  'seafoam-700': 'seafoam-1000',
  'red-400': 'red-800',
  'red-500': 'red-900',
  'red-600': 'red-1000',
  'red-700': 'red-1100',
  'orange-400': 'orange-600',
  'orange-500': 'orange-700',
  'orange-600': 'orange-800',
  'orange-700': 'orange-900',
  'green-400': 'green-800',
  'green-500': 'green-900',
  'green-600': 'green-1000',
  'green-700': 'green-1100',
  'blue-400': 'blue-800',
  'blue-500': 'blue-900',
  'blue-600': 'blue-1000',
  'blue-700': 'blue-1100',
  'gray-50': 'gray-50',
  'gray-75': 'gray-75',
  'gray-100': 'gray-100',
  'gray-200': 'gray-200',
  'gray-300': 'gray-300',
  'gray-400': 'gray-400',
  'gray-500': 'gray-500',
  'gray-600': 'gray-600',
  'gray-700': 'gray-700',
  'gray-800': 'gray-800',
  'gray-900': 'gray-900'
};

const darkV5ColorsToV6Colors = {
  'celery-400': 'celery-800',
  'celery-500': 'celery-900',
  'celery-600': 'celery-1000',
  'celery-700': 'celery-1100',
  'chartreuse-400': 'chartreuse-900',
  'chartreuse-500': 'chartreuse-1000',
  'chartreuse-600': 'chartreuse-1100',
  'chartreuse-700': 'chartreuse-1200',
  'yellow-400': 'yellow-1000',
  'yellow-500': 'yellow-1100',
  'yellow-600': 'yellow-1200',
  'yellow-700': 'yellow-1300',
  'magenta-400': 'magenta-600',
  'magenta-500': 'magenta-700',
  'magenta-600': 'magenta-800',
  'magenta-700': 'magenta-900',
  'fuchsia-400': 'fuchsia-600',
  'fuchsia-500': 'fuchsia-700',
  'fuchsia-600': 'fuchsia-800',
  'fuchsia-700': 'fuchsia-900',
  'purple-400': 'purple-600',
  'purple-500': 'purple-700',
  'purple-600': 'purple-800',
  'purple-700': 'purple-900',
  'indigo-400': 'indigo-600',
  'indigo-500': 'indigo-700',
  'indigo-600': 'indigo-800',
  'indigo-700': 'indigo-900',
  'red-400': 'red-600',
  'red-500': 'red-700',
  'red-600': 'red-800',
  'red-700': 'red-900',
  'orange-400': 'orange-800',
  'orange-500': 'orange-900',
  'orange-600': 'orange-1000',
  'orange-700': 'orange-1100',
  'green-400': 'green-700',
  'green-500': 'green-800',
  'green-600': 'green-900',
  'green-700': 'green-1000',
  'blue-400': 'blue-700',
  'blue-500': 'blue-800',
  'blue-600': 'blue-900',
  'blue-700': 'blue-1000'
};

// https://s2.spectrum.corp.adobe.com/page/grays/#migration-guide
const v6ColorsToS2 = {
  'gray-50': 'gray-25',
  'gray-75': 'gray-50',
  'gray-100': 'gray-75',
  'gray-200': 'gray-100',
  'gray-300': 'gray-200' // ???????
};

const backgroundColors = {
  default: 'base',
  disabled: 'disabled',
  transparent: 'transparent',
  'label-gray': null // ???
};

const borderColors = {
  default: 'gray-500', // ???
  hover: 'gray-600',
  down: 'gray-600',
  focus: 'blue-800',
  'mouse-focus': 'blue-900',
  disabled: 'disabled',
  extralight: v6ColorsToS2['gray-100'],
  light: v6ColorsToS2['gray-200'],
  mid: v6ColorsToS2['gray-300'],
  dark: 'gray-400',
  transparent: 'transparent',
  'translucent-dark': 'transparent-black-75',
  'translucent-darker': 'transparent-black-100',
  negative: 'negative',
  notice: 'notice-600',
  positive: 'positive-800',
  informative: 'informative-800'
};

export function convertColor(property: string, value: string, colorVersion: number | null): string | {default: string, dark: string} | null {
  switch (property) {
    case 'background':
    case 'backgroundColor': {
      let color = backgroundColors[value as keyof typeof backgroundColors];
      if (color !== undefined) {
        return color;
      }

      break;
    }
    case 'borderColor':
    case 'borderStartColor':
    case 'borderEndColor':
    case 'borderTopColor':
    case 'borderBottomColor':
    case 'borderXColor':
    case 'borderYColor': {
      let color = borderColors[value as keyof typeof borderColors];
      if (color !== undefined) {
        return color;
      }

      break;
    }
    case 'color':
    case 'outlineColor':
    case 'fill':
    case 'stroke':
      break;
    default:
      return null;
  }

  if (colorVersion === 5) {
    if (value in staticColors) {
      return staticColors[value as keyof typeof staticColors];
    }

    // Get both a light and a dark mapping. This gets the closest color in each theme
    // to what was available in v5.
    // TODO: should we still do this or just map to one color for S2?
    let light = v5ColorsToV6Colors[value as keyof typeof v5ColorsToV6Colors] || value;
    let dark = darkV5ColorsToV6Colors[value as keyof typeof darkV5ColorsToV6Colors];
    if (dark) {
      return {
        default: v6ColorsToS2[light as keyof typeof v6ColorsToS2] || light,
        dark: v6ColorsToS2[dark as keyof typeof v6ColorsToS2] || dark
      };
    }

    return v6ColorsToS2[light as keyof typeof v6ColorsToS2] || light;
  }

  if (colorVersion === 6) {
    return v6ColorsToS2[value as keyof typeof v6ColorsToS2] || value;
  }

  return null;
}

export function convertUnsafeStyleColor(property: string, value: string): string | {default: string, dark: string} | null {
  let m = value.match(/^var\(--spectrum-global-color-(.+)\)$/);
  if (m) {
    return convertColor(property, m[1], 5);
  }

  m = value.match(/^var\(--spectrum-semantic-(.+)-color-(.+)\)$/);
  if (m) {
    return convertColor(property, m[1], 5);
  }

  m = value.match(/^var\(--spectrum-alias-(.+)-color(?:-(.+))?\)$/);
  if (m) {
    return convertColor(property, m[2] || 'default', 5);
  }

  m = value.match(/^var\(--spectrum-(.+)\)$/);
  if (m) {
    return convertColor(property, m[1], 6);
  }

  return null;
}
